package org.timeismoney.payment.service.impl;

import java.util.List;

import org.apache.log4j.Logger;
import org.timeismoney.payment.common.PageBean;
import org.timeismoney.payment.exception.SysException;
import org.timeismoney.payment.model.Unit;
import org.timeismoney.payment.model.UnitLevel;
import org.timeismoney.payment.service.UnitService;

public class UnitServiceImpl extends BaseServiceImpl<Unit, Integer> implements
		UnitService {
	private static Logger	log	= Logger.getLogger(UnitServiceImpl.class);

	public List<Unit> findUnitByParentUnitOrLevel(Unit unit) {
		try {
			String query = generateHQL(unit);
			return getDao().find(query);
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			throw new SysException(e.getMessage(), e);
		}
	}
	
	public List<Unit> findAllLeafUnit(int levelNo) {
		try {
			String query ="from Unit u left join fetch u.parentUnit left join fetch u.unitLevel where 1=1 and u.unitLevel.levelNo = 4";
			return getDao().find(query);
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			throw new SysException(e.getMessage(), e);
		}
	}
	
	public List<Unit> findUnitByName(int levelNo,String levelName) {
		try {
			String query ="from Unit u left join fetch u.parentUnit left join fetch u.unitLevel where 1=1 and u.unitLevel.levelNo = "+levelNo + " and u.unitName='"+levelName + "'";
			return getDao().find(query);
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			throw new SysException(e.getMessage(), e);
		}
	}
	
	//add by chamdenjo@gmail.com
	public void batchInsertUnit(List<String[]> uploadList){
		for (String[] units : uploadList){
			Unit level1Unit = new Unit();
			List<Unit> level1 = findUnitByName(1, units[0]);
			if (level1 != null && level1.size() > 0){
				level1Unit = level1.get(0);//saved level1
				//check level2
				Unit level2Unit = new Unit();
				List<Unit> level2 = findUnitByName(2,units[1]);
				if (level2 != null && level2.size() > 0){
					level2Unit = level2.get(0); //saved level2
					//check level3
					Unit level3Unit = new Unit();
					List<Unit> level3 = findUnitByName(3,units[2]);
					if (level3 != null && level3.size() > 0){
						level3Unit = level3.get(0); //saved level3
						//check level4
						Unit level4Unit = new Unit();
						List<Unit> level4 = findUnitByName(4,units[3]);
						if (level4 != null && level4.size() > 0){
							level4Unit = level4.get(0); //saved level4
						} else{
							//insert level4
							level4Unit.setUnitName(units[3]);
							UnitLevel unitLevel4 = new UnitLevel();
							unitLevel4.setLevelNo(4);
							level4Unit.setUnitLevel(unitLevel4);
							level4Unit.setParentUnit(level3Unit);
							getDao().save(level4Unit);
						}
					}else{
						//insert level3
						level3Unit.setUnitName(units[2]);
						UnitLevel unitLevel3 = new UnitLevel();
						unitLevel3.setLevelNo(3);
						level3Unit.setUnitLevel(unitLevel3);
						level3Unit.setParentUnit(level2Unit);
						getDao().save(level3Unit);
						
						//insert level4
						Unit level4Unit = new Unit();
						level4Unit.setUnitName(units[3]);
						UnitLevel unitLevel4 = new UnitLevel();
						unitLevel4.setLevelNo(4);
						level4Unit.setUnitLevel(unitLevel4);
						level4Unit.setParentUnit(level3Unit);
						getDao().save(level4Unit);
					}
				}else{
					//insert level2
					level2Unit.setUnitName(units[1]);
					UnitLevel unitLevel2 = new UnitLevel();
					unitLevel2.setLevelNo(2);
					level2Unit.setUnitLevel(unitLevel2);
					level2Unit.setParentUnit(level1Unit);
					getDao().save(level2Unit);
					
					//insert level3
					Unit level3Unit = new Unit();
					level3Unit.setUnitName(units[2]);
					UnitLevel unitLevel3 = new UnitLevel();
					unitLevel3.setLevelNo(3);
					level3Unit.setUnitLevel(unitLevel3);
					level3Unit.setParentUnit(level2Unit);
					getDao().save(level3Unit);
					
					//insert level4
					Unit level4Unit = new Unit();
					level4Unit.setUnitName(units[3]);
					UnitLevel unitLevel4 = new UnitLevel();
					unitLevel4.setLevelNo(4);
					level4Unit.setUnitLevel(unitLevel4);
					level4Unit.setParentUnit(level3Unit);
					getDao().save(level4Unit);
				}
			}else{
				//insert level1
				level1Unit.setUnitName(units[0]);
				UnitLevel unitLevel1 = new UnitLevel();
				unitLevel1.setLevelNo(1);
				level1Unit.setUnitLevel(unitLevel1);
				level1Unit.setParentUnit(null);
				getDao().save(level1Unit);
				
				//insert level2
				Unit level2Unit = new Unit();
				level2Unit.setUnitName(units[1]);
				UnitLevel unitLevel2 = new UnitLevel();
				unitLevel2.setLevelNo(2);
				level2Unit.setUnitLevel(unitLevel2);
				level2Unit.setParentUnit(level1Unit);
				getDao().save(level2Unit);
				
				//insert level3
				Unit level3Unit = new Unit();
				level3Unit.setUnitName(units[2]);
				UnitLevel unitLevel3 = new UnitLevel();
				unitLevel3.setLevelNo(3);
				level3Unit.setUnitLevel(unitLevel3);
				level3Unit.setParentUnit(level2Unit);
				getDao().save(level3Unit);
				
				//insert level4
				Unit level4Unit = new Unit();
				level4Unit.setUnitName(units[3]);
				UnitLevel unitLevel4 = new UnitLevel();
				unitLevel4.setLevelNo(4);
				level4Unit.setUnitLevel(unitLevel4);
				level4Unit.setParentUnit(level3Unit);
				getDao().save(level4Unit);
			}
		}
	}
	//end add
	
	private String generateHQL(Unit unit) {
		String query = "from Unit u left join fetch u.parentUnit left join fetch u.unitLevel where 1=1";
		if(unit.getUnitLevel()!=null)
			query+=" and u.unitLevel.levelNo = "+unit.getUnitLevel().getLevelNo();
		if(unit.getParentUnit()!=null)
			query+=" and u.parentUnit.unitNo = "+unit.getParentUnit().getUnitNo();
		return query;
	}

	public PageBean<Unit> findUnitByParentUnitOrLevel(Unit unit,
			PageBean<Unit> pageBean) {
		try {
			String query = generateHQL(unit);
			return getDao().find(query,pageBean);
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			throw new SysException(e.getMessage(), e);
		}
	}

	public List<Unit> getUnitsByUnitLevel(UnitLevel ul) {
		return getDao().find("from Unit u where u.unitLevel = ?", ul);
	}

}
